﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace CTSexercises
{
    public class Student : ICloneable, IComparable<Student>
    {
        #region enums

        public enum University
        {
            SofiaUniversity,
            TechnicalUniversity,
            UNSS
        }

        public enum Faculty
        {
            FMI,
            Electrical,
            Economic,
            Historic
        }

        public enum Speciality
        {
            Informatics,
            ComputerScience,
            History,
            Economics
        }
        #endregion

        #region fields
        private string firstName;
        private string secondName;
        private string lastName;
        private string ssn;
        private string address;
        private University university;
        private Faculty faculty;
        private Speciality speciality;
        #endregion

        public Student(string firstName, string secondName, string lastName, string ssn, string address, University university, Faculty faculty, Speciality speciality)
        {
            this.firstName = firstName;
            this.secondName = secondName;
            this.lastName = lastName;
            this.ssn = ssn;
            this.address = address;
            this.university = university;
            this.faculty = faculty;
            this.speciality = speciality;
        }

        #region Properties

        public string FirstName
        {
            get
            {
                return firstName;
            }
            set
            {
                firstName = value;
            }
        }

        public string SecondName
        {
            get
            {
                return secondName;
            }
            set
            {
                secondName = value;
            }
        }

        public string LastName
        {
            get
            {
                return lastName;
            }
            set
            {
                lastName = value;
            }
        }

        public string Ssn
        {
            get
            {
                return ssn;
            }
            set
            {
                ssn = value;
            }
        }

        public string Address
        {
            get
            {
                return address;
            }
            set
            {
                address = value;
            }
        }

        public University UniversityName
        {
            get
            {
                return university;
            }
            set
            {
                university = value;
            }
        }

        public Faculty FacultyName
        {
            get
            {
                return faculty;
            }
            set
            {
                faculty = value;
            }
        }

        public Speciality Special
        {
            get
            {
                return speciality;
            }
            set
            {
                speciality = value;
            }
        }
        #endregion

        public override bool Equals(object obj)
        {
            Student other = obj as Student;
            if (other == null)
            {
                throw new FormatException("Cannot compare different types.");
            }

            if (!this.firstName.Equals(other.firstName))
            {
                return false;
            }
            else if (!this.secondName.Equals(other.secondName))
            {
                return false;
            }
            else if (!this.lastName.Equals(other.lastName))
            {
                return false;
            }
            else if (!this.ssn.Equals(other.ssn))
            {
                return false;
            }
            else if (!this.address.Equals(other.Address))
            {
                return false;
            }
            else if (!this.university.Equals(other.university))
            {
                return false;
            }
            else if (!this.faculty.Equals(other.faculty))
            {
                return false;
            }
            else if (!this.speciality.Equals(other.speciality))
            {
                return false;
            }

            return true;
        }

        public override int GetHashCode()
        {
            return
                this.firstName.GetHashCode() ^ this.secondName.GetHashCode() ^
                this.lastName.GetHashCode() ^ this.ssn.GetHashCode() &
                this.address.GetHashCode() & this.university.GetHashCode() &
                this.faculty.GetHashCode() & this.speciality.GetHashCode();
        }

        public override string ToString()
        {
            StringBuilder output = new StringBuilder();

            output.Append(firstName);
            output.Append(" ");
            output.Append(secondName);
            output.Append(" ");
            output.AppendLine(lastName);
            output.AppendLine(address);
            output.AppendLine(university.ToString());
            output.AppendLine(faculty.ToString());
            output.AppendLine(speciality.ToString());

            return output.ToString();
        }

        public static bool operator ==(Student s1, Student s2)
        {
            return s1.Equals(s2);
        }

        public static bool operator !=(Student s1, Student s2)
        {
            return !s1.Equals(s2);
        }

        public object Clone()
        {
            Student newStudent = new Student
                (this.firstName, this.secondName, this.lastName, this.ssn, this.address,
                this.university, this.faculty, this.speciality);

            return newStudent;
        }

        public int CompareTo(Student other)
        {
            if (this.firstName.CompareTo(other.firstName) != 0)
            {
                return this.firstName.CompareTo(other.firstName);
            }
            else if (this.secondName.CompareTo(other.secondName) != 0)
            {
                return this.secondName.CompareTo(other.secondName);
            }
            else if (this.lastName.CompareTo(other.lastName) != 0)
            {
                return this.lastName.CompareTo(other.lastName);
            }
            else if (this.ssn.CompareTo(other.ssn) != 0)
            {
                return this.ssn.CompareTo(other.ssn);
            }

            return 0;
        }

    }
}
